package com.riekoff.particlecubeworld.player;

import cc.creativecomputing.CCApp;
import cc.creativecomputing.CCApplicationManager;
import cc.creativecomputing.control.CCControl;
import cc.creativecomputing.events.CCKeyEvent;
import cc.creativecomputing.graphics.CCColor;
import cc.creativecomputing.graphics.shader.CCGLSLShader;
import cc.creativecomputing.graphics.texture.CCTexture.CCTextureTarget;
import cc.creativecomputing.graphics.texture.CCTexture2D;
import cc.creativecomputing.graphics.texture.CCTextureData;
import cc.creativecomputing.io.CCIOUtil;
import cc.creativecomputing.math.CCMath;

import com.riekoff.particlecubeworld.editor.visual.ABoxVisualFinal;

import de.negativrekord.blockworld.BlockWorld;
import de.negativrekord.blockworld.KnnClassifier2;


public class ATileworldAppClasses extends CCApp {
	
	public class ClassifiyControl {
		@CCControl(name="Blend Patterns", min=0,max=1)
		int blendPatterns = 1;
		
		@CCControl(name="Blend Zones", min=0,max=1)
		int blendZones = 1;
		
		@CCControl(name="Blend Colors", min=0,max=1)
		int blendColors = 1;
	}
	
	@CCControl(name="blend control", tabName="blend control")
	ClassifiyControl _cClas = new ClassifiyControl();
	
	@CCControl(name = "tile raster size", min = 0.001f, max = 1f)
	private float _cTileRasterWidth = 0.1f;
	
	@CCControl(name = "motar thickness", min = 0.0001f, max = 1f)
	private float _cMotarThickness = 0.01f;
	
	@CCControl(name = "motar smooth", min = 0.0001f, max = 1f)
	private float _cMotarSmooth = 0.01f;
	
	@CCControl(name = "motar edge smooth", min = 0.0001f, max = 0.01f)
	private float _cMotarEdgeSmooth = 0.01f;
	
	@CCControl(name = "motar hue", min = 0, max = 1)
	private float motarHue = 0;
	
	@CCControl(name = "motar saturation", min = 0, max = 1)
	private float motarSaturation = 0;
	
	@CCControl(name = "motar brightness", min = 0, max = 1)
	private float motarBrightness = 0;
	
	@CCControl(name = "pattern index", min = 0, max = 25)
	private int _cPatternIndex = 0;
	
	@CCControl(name = "color index", min = 0, max = 100)
	private int _cColorIndex = 0;
	
	@CCControl(name = "zone index", min = 0, max = 100)
	private int _cZoneIndex = 0;
	
	@CCControl(name = "zone scale", min = 0, max = 1)
	private float _cZoneScale = 0;
	
	@CCControl(name = "debug")
	public static boolean _cDebug = false;
	
	@CCControl(name="blockworld", tabName="blockworld")
	public ABoxVisualFinal _myBlockworldVisual;
	
	
	private CCGLSLShader _myShader;
	private CCGLSLShader _mySimpleShader;
	private KnnClassifier2 _myClassifier = new KnnClassifier2(10, 800);
	
	private CCTexture2D _myRandomTexture;
	private APatterns _myPatterns;
	private AColorMaps _myColorMaps;
	private AZones _myZones;
	private float _myTime = 0;
	
	
	
	@Override
	public void setup() {
		
//		_myPatterns = new APatterns(g);
//		_myColorMaps = new AColorMaps();
//		_myZones = new AZones();
		_myBlockworldVisual = new ABoxVisualFinal(this);
		
		addControls("app", "app", this);
		
		_myShader = new CCGLSLShader(
			CCIOUtil.classPath(this, "tex_brick_vertex.glsl"),
			CCIOUtil.classPath(this, "tex_brick_fragment.glsl")
		);
		_myShader.load();
	
		_mySimpleShader = new CCGLSLShader(
				CCIOUtil.classPath(BlockWorld.class, "shader/display_simple_vp.glsl"),
				CCIOUtil.classPath(BlockWorld.class, "shader/display_simple_fp.glsl")
			);
		_mySimpleShader.load();
		
			
		
		CCTextureData myRandom = new CCTextureData(200,200);
		for(int x = 0; x < myRandom.width(); x++ ){
			for(int y = 0; y < myRandom.height(); y++ ){
				myRandom.setPixel(x, y, new CCColor(CCMath.random(),CCMath.random(),CCMath.random()));
			}
		}
		_myRandomTexture = new CCTexture2D(myRandom, CCTextureTarget.TEXTURE_RECT);
	}

	boolean mute = false;
	@Override
	public void keyPressed (CCKeyEvent theEvent) {
		
	}
	
	@Override
	public void update(final float theDeltaTime) {
		_myTime += theDeltaTime;
		_myBlockworldVisual.update(theDeltaTime);
		_myClassifier.update(theDeltaTime);
	}
	
	@Override
	public void draw() {

		g.clear();
		g.color(255);
		//g.polygonMode(CCPolygonMode.LINE);
		drawSimple();
		g.camera().draw(g);
	}
		
	public void drawSimple() {
		
		g.color(1f);
		_mySimpleShader.start();
		
//		_mySimpleShader.uniform3fv("centers0", _myClassifier.centers0());
//		_mySimpleShader.uniform4fv("classes0", _myClassifier.classes0());
//		
//		_mySimpleShader.uniform3fv("centers1", _myClassifier.centers1());
		
		
		
		_myBlockworldVisual.draw(g);
		_mySimpleShader.end();
		
		/*
		g.color(1f,1f,0);
		for (CCVector3f v: _myClassifier.centers1()) {
			g.pushMatrix();
			g.translate(v);
			g.box(30,30,30);
			g.popMatrix();
		}
		*/
	}
	
	public void drawShader() {	
		g.clear();
		g.color(255);
		_myShader.start();
		g.texture(0, _myPatterns.texture());
		g.texture(1, _myZones.texture());
		g.texture(2, _myColorMaps.texture());
		
		g.texture(3,_myRandomTexture);
		
		float tileMotarWidth = 1;
		float motarStep = _cMotarThickness;
		
		_myShader.uniform1f("tileMotarWidth", tileMotarWidth);
		_myShader.uniform1f("motarStep", motarStep);
		_myShader.uniform1f("motarSmooth", _cMotarSmooth);
		_myShader.uniform1f("motarEdgeSmooth", _cMotarEdgeSmooth);
		
		_myShader.uniform4f("motarColor", CCColor.createFromHSB(motarHue, motarSaturation, motarBrightness));
		_myShader.uniform1f("patternScale", _cTileRasterWidth);
		_myShader.uniform1i("debug", _cDebug ? 1 : 0);
		
		_myShader.uniform1i("random", 3);
		_myShader.uniform1f("time", _myTime * 30);
		
		_myShader.uniform1i("patterns", 0);
		_myShader.uniform1i("patternIndex", _cPatternIndex);
		_myShader.uniform2fv("patternDimensions", _myPatterns.dimension());
		
		_myShader.uniform1i("zones", 1);
		_myShader.uniform1i("zoneIndex", _cZoneIndex);
		_myShader.uniform3fv("zoneDimensions", _myZones.zoneInfos());
		float[] zoneScales = new float[100];
		for(int i = 0; i < 100;i++){
			zoneScales[i] = _cZoneScale;
		}
		_myShader.uniform1fv("zoneScales",zoneScales);
		_myShader.uniform1i("colorMaps", 2);
		_myShader.uniform1i("colorIndex", _cColorIndex);
	
		
		
		
		_myShader.uniform3fv("centersPattern", _myBlockworldVisual.centersPattern());
		_myShader.uniform3fv("centersZone", _myBlockworldVisual.centersZone());
		_myShader.uniform3fv("centersColor", _myBlockworldVisual.centersColor());
		for (int i=0; i<10; i++) {
			_myShader.uniform3f("cl"+i, _myBlockworldVisual.centersColor()[i]);
		}
		_myShader.uniform1i("blendPatterns", _cClas.blendPatterns);
		_myShader.uniform1i("blendColors", _cClas.blendColors);
		_myShader.uniform1i("blendZones", _cClas.blendZones);
		
		
		_myBlockworldVisual.draw(g);
		
		g.noTexture();
		_myShader.end();
		
		/*
		for (CCVector3f v: _myBlockworldVisual.centersColor()) {
			g.pushMatrix();
			g.translate(v);
			g.box(2,2,2);
			g.popMatrix();
		}
		*/
	}

	public static void main(String[] args) {
		CCApplicationManager myManager = new CCApplicationManager(ATileworldAppClasses.class);
		myManager.settings().size(1920*1.3f, 1080*1.2f/3);
		myManager.settings().display(0);
		myManager.start();
	}
}
